package com.example.demo.util;

import okhttp3.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

/**
 * http工具类，基于okhttp
 * @author sunt
 * @date 2017年8月31日 上午10:01:48
 */
public abstract class HttpUtil {

    static final Logger log = LoggerFactory.getLogger(HttpUtil.class);
    
    public static final int CONNECT_TIMEOUT = 60;
    public static final int READ_TIMEOUT = 60;     //300
    public static final int WRITE_TIMEOUT = 60;   //3600

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    
    public static final MediaType APPLICATION_FORM_URLENCODED = MediaType.parse("application/x-www-form-urlencoded");
    
    
    public static final OkHttpClient client = new OkHttpClient.Builder().readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)// 设置读取超时时间
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)// 设置写的超时时间
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)// 设置连接超时时间
            .sslSocketFactory(OkHttpSSLUtil.createSSLSocketFactory(),new OkHttpSSLUtil.TrustAllManager())
            .hostnameVerifier(new OkHttpSSLUtil.TrustAllHostnameVerifier())
            .build();

    
    /**
     * get请求
     * @param url
     * @return
     */
    public static String get(String url){
        if(StringUtils.isBlank(url)) throw new RuntimeException("url不能为空");
        Request request = new Request.Builder().url(url).build();
        try(Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (IOException e) {
            log.error("访问异常:"+url, e);
            throw new RuntimeException("访问异常:"+url);
        }
    }

    /**
     * post提交json数据
     * @param url
     * @param json
     * @return
     */
    public static String postJSON(String url, String json) {
        if(StringUtils.isBlank(url)) throw new RuntimeException("url不能为空");
        RequestBody body = RequestBody.create(JSON, json);
        Request request = new Request.Builder().url(url).post(body).build();
        try(Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (IOException e) {
            log.error("访问异常:"+url, e);
            throw new RuntimeException("访问异常:"+url);
        }
    }
    
    
    /**
     * post提交form 
     * @param url
     * @param form 示例： param1=value1&param2=value2
     * @return
     */
    public static String postForm(String url, String form) {
        if(StringUtils.isBlank(url)) throw new RuntimeException("url不能为空");
        RequestBody body = RequestBody.create(APPLICATION_FORM_URLENCODED, form);
        Request request = new Request.Builder().url(url).post(body).build();
        try(Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (IOException e) {
            log.error("访问异常:"+url, e);
            throw new RuntimeException("访问异常:"+url);
        }
    }
    
    /**
     * post提交form 参数值会被编码URLEncoder.encode("","UTF-8")
     * @param url
     * @param params
     * @return
     */
    public static String postForm(String url,LinkedHashMap<String, Object> params) {
        if(StringUtils.isBlank(url)) throw new RuntimeException("url不能为空");
        RequestBody body = RequestBody.create(APPLICATION_FORM_URLENCODED, encodeValue(params,"UTF-8"));
        Request request = new Request.Builder().url(url).post(body).build();
        try(Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (IOException e) {
            log.error("访问异常:"+url, e);
            throw new RuntimeException("访问异常:"+url);
        }
    }
    /**
     * post提交form
     * @param url
     * @param params
     * @param encode 参数值编码方式 UTF-8 GBK
     * @return
     */
    public static String postForm(String url,LinkedHashMap<String, Object> params,String encode) {
        if(StringUtils.isBlank(url)) throw new RuntimeException("url不能为空");
        RequestBody body = RequestBody.create(APPLICATION_FORM_URLENCODED, encodeValue(params,encode));
        Request request = new Request.Builder().url(url).post(body).build();
        try(Response response = client.newCall(request).execute()) {
            return response.body().string();
        } catch (IOException e) {
            log.error("访问异常:"+url, e);
            throw new RuntimeException("访问异常:"+url);
        }
    }
    
    /**
     * 将参数值进行编码URLEncoder.encode(value,"UTF-8")
     * @param params
     * @return
     */
    public static String encodeUtf8(Map<String,Object> params) {
        return encodeValue(params, "UTF-8");
    }
    /**
     * 将参数值进行编码
     * @param params
     * @param encode UTF-8 GBK
     * @return like  a=v1&b=v2
     */
    public static String encodeValue(Map<String,Object> params,String encode) {
        if(MapUtils.isNotEmpty(params)) {
            StringBuilder sb = new StringBuilder();
            for (Entry<String, Object> entry : params.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                sb.append(key).append("=");
                if(value instanceof String) {
                    try {
                        sb.append(URLEncoder.encode((String)value, encode)).append("&");
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException("encode失败："+key+"="+value,e);
                    }
                }else {
                    sb.append(String.valueOf(value)).append("&");
                }
            }
            return sb.toString().substring(0, sb.length()-1);
        }
        return null;
    }
    
    
    public static void main(String[] args) {
//        String re = get("https://id.pdedu.sh.cn/.well-known/openid-configuration/jwks");
//        System.out.println(re);
//        System.out.println(get("http://localhost:8080/test/1?v=123"));
//        LinkedHashMap<String,Object> params = new LinkedHashMap<>();
//        params.put("client_id", "lesson99.com");
//        params.put("client_secret", "b871c2bf63564d1a968b30bf1951b9be");
//        params.put("code", "123");
//        params.put("grant_type", "authorization_code");
//        params.put("redirect_uri", "http://zj.lesson99.com:8081/");
//        String re = postForm("https://id.pdedu.sh.cn/connect/token", params);
//        System.out.println(re);
    }
}
